//
// MessageBox.h
// Usage: Process message box. For IPC.
// CreateDate: 2009-05-15
// Author: MaJiuyue
//
#ifndef _MESSAGEBOX_H_
#define _MESSAGEBOX_H_

#include <NewLife.h>
#include <LinkedList.h>

/* Message type */
struct MESSAGE
{
	size_t size;
	pid_t pid;
	char dat;
};
typedef struct MESSAGE * MESSAGE_PTR;

/* mqueue type */
enum MQUEUE_TYPE { KNL_MBOX, USR_MBOX, MQUEUE_SIZE };

class MessageBox
{
private:
	/* Message queue */
	LinkedList<MESSAGE_PTR> mqueue[MQUEUE_SIZE];
	/* User mbox size */
	const int umbox_size;

	/* User process is wait for this process send message */
	bool bWait;
	pid_t wait_pid;
	MESSAGE * wait_buf;

public:
	/* construct a mbox with size 'capacity' */
	MessageBox(int capacity);
	MessageBox(const MessageBox &target);
	~MessageBox();

public:
	/* Put a message to this mbox, if mbox is full, return false. */
	bool PutMessage(MQUEUE_TYPE type, MESSAGE *msg);
	/* 
	   Get a message from this mbox(send by pid).
	     1. if mbox is empty, return false.
	     2. if mbox have no message from pid,
	        set 'wait_pid' to pid, return false.
	*/
	bool GetMessage(pid_t pid, MESSAGE *msg);
	
	/* Check if mbox is full */
	bool IsFull();
	/* Check if mbox is empty */
	bool IsEmpty();
	/* Check if mbox is waiting for message from pid */
	bool IsWaitingFor(pid_t pid);
	/* Reset wait */
	void ResetWait();
	/* Get wait buffer */
	MESSAGE * GetWaitBuffer() { return wait_buf; }

	/* Clean this mbox */
	void ClearBox();
};

#endif

